﻿using Newtonsoft.Json;
using SerialPort_Assistant.Enums;
using SerialPort_Assistant.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SerialPort_Assistant.Config
{
    [Serializable]
    public class AppConfig
    {
        // 可以用该特性来解决属性名称不一致的情况
        [DisplayName("FileName")]
        public  string FileName { get; set; }
        public  string PortName { get; set; }
        public  int? BaudRate { get; set; }
        public  Parity? Parity { get; set; }
        public  int? DataBits { get; set; }
        public  StopBits? StopBits { get; set; }
        public  int? Interval { get; set; }
        public  int? TimeUnitType { get; set; }
        public  bool? ShowRecv { get; set; }
        public  ShowTypes? ShowType { get; set; }
        public  SendTypes? SendType { get; set; }
        public  SendWays? SendWay { get; set; }
        public int? ReadTimeout { get; set; }

        /// <summary>
        /// 硬编码方式还原配置
        /// </summary>
        /// <param name="viewModel"></param>
        public void LoadAppConfig(MainViewModel viewModel)
        {
            if (!string.IsNullOrEmpty(FileName))
            {
                viewModel.FileName = FileName;
            }

            if (!string.IsNullOrEmpty(PortName))
            {
                viewModel.PortName = PortName;
            }

            if (BaudRate.HasValue)
            {
                viewModel.BaudRate = BaudRate.Value;
            }

            if (Parity.HasValue)
            {
                viewModel.Parity = Parity.Value;
            }

            if (DataBits.HasValue)
            {
                viewModel.DataBits = DataBits.Value;
            }

            if (StopBits.HasValue)
            {
                viewModel.StopBits = StopBits.Value;
            }

            if (Interval.HasValue)
            {
                viewModel.Interval = Interval.Value;
            }

            if (TimeUnitType.HasValue)
            {
                viewModel.TimeUnitType = TimeUnitType.Value;
            }

            if (ShowRecv.HasValue)
            {
                viewModel.ShowRecv = ShowRecv.Value;
            }

            if (ShowType.HasValue)
            {
                viewModel.ShowType = ShowType.Value;
            }

            if (SendType.HasValue)
            {
                viewModel.SendType = SendType.Value;
            }

            if(SendWay.HasValue)
            {
                viewModel.SendWay = SendWay.Value;
            }

            if (ReadTimeout.HasValue)
            {
                viewModel.ReadTimeout = ReadTimeout.Value;
            }
        }

        /// <summary>
        /// 通过反射动态还原配置
        /// 注意： 这里需要保证 配置类 中的属性名称与 MainViewModel 中的属性名称相同
        /// </summary>
        /// <param name="viewModel"></param>
        public void LoadAppConfigByReflect(MainViewModel viewModel)
        {
            var properties = typeof(AppConfig).GetProperties();

            foreach (var property in properties)
            {
                var value = property.GetValue(null);
                if (value != null)
                {
                    property.SetValue(viewModel, value);
                }
            }
        }

        /// <summary>
        /// 通过反射和特性动态还原配置，通过特性解决 配置类 与 MainViewModel 属性名称不一致的情况
        /// </summary>
        /// <param name="viewModel"></param>
        public void LoadAppConfigByReflectAndAttribute(MainViewModel viewModel)
        {
            var properties = typeof(AppConfig).GetProperties();

            foreach (var property in properties)
            {
                var displayName = ((DisplayNameAttribute)Attribute.GetCustomAttribute(property, typeof(DisplayNameAttribute)))?.DisplayName;

                if (string.IsNullOrEmpty(displayName))
                {
                    continue;
                }

                var value = property.GetValue(null);

                var viewModelProperty = typeof(MainViewModel).GetProperty(displayName);
                if (viewModelProperty != null && value != null)
                {
                    viewModelProperty.SetValue(viewModel, value);
                }
            }
        }
    }
}
